#include<iostream>
#include<sys/socket.h>
#include<netinet/in.h>
#include<cstring>
#include"Log.hpp"
#include"InetAddr.hpp"
#include<assert.h>

using namespace hcc;

#define MAX_SIZE 4096
class Server
{
    public:
    Server(uint16_t port):_port(port),_listensock(-1),_isrunning(false)
    {
        _listensock=socket(AF_INET,SOCK_STREAM,0);
        if(_listensock<0)
        {
            exit(-1);
        }
        LOG(DEBUG,"create sockfd success\n");
        struct sockaddr_in addr;
        memset(&addr,0,sizeof(addr));
        addr.sin_family=AF_INET;
        addr.sin_port=htons(port);
        addr.sin_addr.s_addr=INADDR_ANY;

        socklen_t len=sizeof(addr);
        int ret=::bind(_listensock,(struct sockaddr*)&addr,len);
        if(ret<0)
        {
            exit(-1);
        }
        LOG(DEBUG,"bind success\n");

         ret=::listen(_listensock,10);
        if(ret<0)
        {
            exit(-1);
        }
        LOG(DEBUG,"listen success\n");
    }

    void Loop()
    {
        _isrunning=true;
        while(_isrunning)
        {
            struct sockaddr_in client;
            socklen_t len=sizeof(client);
            int sockfd=::accept(_listensock,(struct sockaddr*)&client,&len);
            if(sockfd<0)
            {
                LOG(DEBUG,"accept failed!\n");
                continue;
            }
            LOG(DEBUG,"accept success!\n");
            InetAddr addr(client);
            Service(sockfd,addr);

        }
    }
    void Service(int sockfd,InetAddr client)
    {
        char buffer[MAX_SIZE];
        while(true)
        {
            ssize_t n=read(sockfd,&buffer,sizeof(buffer)-1);
            if(n<0)
            {
                LOG(ERROR,"read error!\n");
                break;
            }
            else if(n==0)
            {
                LOG(DEBUG,"client quit,client ip: %s \n",client.Ip().c_str());
                break;
            }
            else 
            {
                buffer[n]=0;
                std::cout<<"client say : "<<buffer<<std::endl;
            }
            std::string echo="server echo : ";
            echo+=buffer;
            ssize_t ret=write(sockfd,echo.c_str(),echo.size());
        }
    }
private:
    int _listensock;
    bool _isrunning ;
    uint16_t _port;
};